昨天我們介紹了 Union 和 Enum,今天要進一步學習如何用 Interface、Type、Generics 來讓程式更有結構、更可重用。
這次一樣用「搭火車」的例子 🚄,幫助你快速理解!
介面用來定義「物件的形狀」,就像規劃「火車乘客」需要有什麼資料。
interface Passenger {
  id: number;
  name: string;
  seat?: string; // 可選屬性(可能沒劃位)
}
const passengerA: Passenger = {
  id: 1,
  name: "Arvin",
};
const passengerB: Passenger = {
  id: 2,
  name: "Alice",
  seat: "A12",
};
👉 特點:
interface VipPassenger extends Passenger {
  loungeAccess: boolean;
}
const vip: VipPassenger = {
  id: 3,
  name: "Bob",
  seat: "B10",
  loungeAccess: true,
};
type 與 interface 很像,不過它更靈活,不只可以描述物件,還能用來定義 聯合型別、基本型別別名。
// 車票編號可能是數字或字串
type TicketID = number | string;
// 乘客物件
type PassengerType = {
  id: TicketID;
  name: string;
};
const passengerC: PassengerType = {
  id: "T-123",
  name: "Charlie",
};
👉 差異比較:
泛型就像「火車車廂」🚃:
同樣的車廂結構,可以載不同種類的乘客或貨物。
function identity<T>(value: T): T {
  return value;
}
// 明確指定型別
const ticketNumber = identity<number>(12345);
const passengerName = identity<string>("David");
// 也可以自動推斷
const autoTicket = identity("E12");
interface TrainResponse<T> {
  status: number;
  data: T;
}
// 回傳單一乘客
const passengerResponse: TrainResponse<Passenger> = {
  status: 200,
  data: { id: 1, name: "Arvin" },
};
// 回傳乘客陣列
const passengersResponse: TrainResponse<Passenger[]> = {
  status: 200,
  data: [
    { id: 2, name: "Alice" },
    { id: 3, name: "Bob", seat: "C3" },
  ],
};
class TrainCar<T> {
  private items: T[] = [];
  add(item: T) {
    this.items.push(item);
  }
  getAll(): T[] {
    return this.items;
  }
}
// 建立「乘客車廂」
const passengerCar = new TrainCar<Passenger>();
passengerCar.add({ id: 1, name: "Arvin" });
passengerCar.add({ id: 2, name: "Alice" });
// 建立「行李車廂」
const luggageCar = new TrainCar<string>();
luggageCar.add("背包");
luggageCar.add("行李箱");
console.log(passengerCar.getAll());
console.log(luggageCar.getAll());
| 特點 | Interface | Type | Generics | 
|---|---|---|---|
| 用途 | 定義物件結構 | 定義各種型別(物件、Union、Tuple…) | 建立可重用、保留型別的模板 | 
| 延伸性 | 可用 extends繼承、擴充 | 不可繼承,但可用 &做交集合併 | 可套用在函式、介面、類別 | 
| 優點 | 清楚描述物件結構、支援擴充 | 彈性大,可用於各種型別組合 | 可重用,提高型別安全性 | 
👉 明天(Day 6)我們會開始進入實戰的一個全新篇章,開始初始化一個 TypeScript + Node.js 專案 !